package com.bwstudio.demo.consumer.message;

import java.math.BigDecimal;

import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.bwstudio.demo.consumer.dao.AccountInfoDao;
import com.bwstudio.demo.consumer.message.template.MsgProcessTemplateV2;
import com.bwstudio.demo.consumer.model.AccountChangeEvent;
import com.bwstudio.demo.consumer.service.AccountInfoService;

import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
@RocketMQMessageListener(topic = "topic_txmsg", 
	selectorExpression = "v2",
	consumerGroup = "${spring.application.name}-txmsg-bank2-v2")
public class TxmsgConsumerV2 implements RocketMQListener<String> {

    @Autowired
    AccountInfoDao accountInfoDao;
    
    @Autowired
    AccountInfoService accountInfoService;

    //接收消息
    @Override
    public void onMessage(String message) {
        new MsgProcessTemplateV2<AccountChangeEvent>() {

			@Override
			protected AccountChangeEvent doParse(String jsonStr) {
				JSONObject jsonObject = JSONObject.parseObject(jsonStr);
		        String accountChangeString = jsonObject.getString("accountChange");
		        //转成AccountChangeEvent
		        AccountChangeEvent accountChangeEvent = JSONObject.parseObject(accountChangeString, AccountChangeEvent.class);
				return accountChangeEvent;
			}

			@Override
			protected void msgBodyValidate(AccountChangeEvent t) throws RuntimeException {
//		        if(StringUtils.equals(t.getAccountNo(), "2")) {
//		        	throw new RuntimeException("转入bank2的账户不正确");
//		        }
			}

			@Override
			protected void checkTxNoIsExisted(AccountChangeEvent t) throws RuntimeException {
				if (accountInfoDao.isExistTx(t.getTxNo()) > 0) {
					return;
				}
			}

			@Override
			@Transactional
			protected void doUpdateDB(AccountChangeEvent t) {
		        //设置账号为李四的
		        t.setAccountNo("2");
				// 增加金额
				accountInfoDao.updateAccountBalance(t.getAccountNo(), t.getAmount());
				// 添加事务记录，用于幂等
				accountInfoDao.addTx(t.getTxNo());
				if (t.getAmount().compareTo(new BigDecimal(4)) == 0) {
					throw new RuntimeException("人为制造异常");
				}
			}
        }.doProcess(message);

    }
}
